{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-09-27T11:18:38.977425Z",
     "start_time": "2025-09-27T11:18:36.943978Z"
    }
   },
   "source": [
    "from tqdm import tqdm\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "import torch\n",
    "\n",
    "from PIL import Image\n",
    "\n",
    "# 忽略烦人的红色提示\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "# 有 GPU 就用 GPU，没有就用 CPU\n",
    "device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')\n",
    "print('device', device)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "device cuda:0\n"
     ]
    }
   ],
   "execution_count": 1
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-27T11:18:42.065029Z",
     "start_time": "2025-09-27T11:18:40.548736Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from torchvision import transforms\n",
    "transform = transforms.Compose([transforms.Resize((64, 64)),\n",
    "                                transforms.ToTensor(),\n",
    "                                transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n",
    "                                ])"
   ],
   "id": "4f42435170459e6f",
   "outputs": [],
   "execution_count": 2
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-27T11:18:43.766900Z",
     "start_time": "2025-09-27T11:18:43.599683Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from zsl_ma.models.VAE import Encoder\n",
    "from zsl_ma.models.CNN import create_resnet, CNN\n",
    "from zsl_ma.models.projection import FeatureProjectionModel\n",
    "\n",
    "# model = FeatureProjectionModel(embed_dim=512)\n",
    "# model= create_resnet(weight_path=r'D:\\Code\\2-ZSL\\1-output\\特征解耦结果\\HOB\\exp-2\\checkpoints\\cnn.pth')\n",
    "# model.load_state_dict(torch.load(r'D:\\Code\\2-ZSL\\1-output\\特征解耦结果\\HOB\\exp-2\\checkpoints\\feature_projection.pth'))\n",
    "# model = CNN(4)\n",
    "model = Encoder()\n",
    "model.load_state_dict(torch.load(r'D:\\Code\\2-ZSL\\1-output\\特征解耦结果\\HOB\\exp-3\\checkpoints\\encoder.pth'))\n",
    "model = model.to(device)\n"
   ],
   "id": "789fff5be780f06a",
   "outputs": [],
   "execution_count": 3
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-27T11:18:45.680349Z",
     "start_time": "2025-09-27T11:18:45.673675Z"
    }
   },
   "cell_type": "code",
   "source": "model",
   "id": "949ebc6ad6f6155c",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Encoder(\n",
       "  (conv1): Sequential(\n",
       "    (0): Conv2d(3, 16, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))\n",
       "    (1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "    (2): ReLU()\n",
       "    (3): ResidualBlock(\n",
       "      (res): Sequential(\n",
       "        (0): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "        (1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (2): ReLU()\n",
       "        (3): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "        (4): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (5): ReLU()\n",
       "      )\n",
       "    )\n",
       "  )\n",
       "  (conv2): Sequential(\n",
       "    (0): Conv2d(16, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))\n",
       "    (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "    (2): ReLU()\n",
       "    (3): ResidualBlock(\n",
       "      (res): Sequential(\n",
       "        (0): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "        (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (2): ReLU()\n",
       "        (3): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "        (4): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (5): ReLU()\n",
       "      )\n",
       "    )\n",
       "  )\n",
       "  (conv3): Sequential(\n",
       "    (0): Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))\n",
       "    (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "    (2): ReLU()\n",
       "    (3): ResidualBlock(\n",
       "      (res): Sequential(\n",
       "        (0): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "        (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (2): ReLU()\n",
       "        (3): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "        (4): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (5): ReLU()\n",
       "      )\n",
       "    )\n",
       "  )\n",
       "  (conv4): Sequential(\n",
       "    (0): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "    (2): ReLU()\n",
       "    (3): ResidualBlock(\n",
       "      (res): Sequential(\n",
       "        (0): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "        (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (2): ReLU()\n",
       "        (3): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "        (4): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (5): ReLU()\n",
       "      )\n",
       "    )\n",
       "  )\n",
       "  (flatten): Flatten(start_dim=1, end_dim=-1)\n",
       "  (fc): Linear(in_features=8192, out_features=512, bias=True)\n",
       ")"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 4
  },
  {
   "metadata": {},
   "cell_type": "code",
   "source": [
    "from torchvision.models.feature_extraction import create_feature_extractor\n",
    "target_layers = {\n",
    "    'fc.1': 'output',\n",
    "}\n",
    "model_trunc = create_feature_extractor(model, return_nodes=target_layers).to(device)\n",
    "model_trunc"
   ],
   "id": "3e42dba8b3c58e92",
   "outputs": [],
   "execution_count": null
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-27T11:18:50.796867Z",
     "start_time": "2025-09-27T11:18:48.805862Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from zsl_ma.tools.tool import generate_image_dataframe\n",
    "\n",
    "# df = pd.read_csv(r'D:\\Code\\2-ZSL\\1-output\\特征解耦结果\\exp-3\\val.csv', encoding=\"utf-8-sig\")\n",
    "df, _=generate_image_dataframe(r'D:\\Code\\2-ZSL\\0-data\\HOB\\dataset', 'train',\n",
    "                               class_list_path=r'D:\\Code\\2-ZSL\\0-data\\HOB\\dataset/seen_classes.txt',need_parse_factors=False)\n",
    "df.to_csv(r'D:\\Code\\2-ZSL\\1-output\\特征解耦结果\\HOB\\exp-3\\可见类数据集.csv', index=False, encoding='utf-8-sig')"
   ],
   "id": "144fd1096d2f7ced",
   "outputs": [],
   "execution_count": 5
  },
  {
   "metadata": {},
   "cell_type": "code",
   "source": "df.head()",
   "id": "2f7113dcb3c91a7b",
   "outputs": [],
   "execution_count": null
  },
  {
   "metadata": {},
   "cell_type": "code",
   "source": "df['标注类别名称']",
   "id": "1b2796c76bd4b2f0",
   "outputs": [],
   "execution_count": null
  },
  {
   "metadata": {},
   "cell_type": "code",
   "source": [
    "target_part = '0'\n",
    "part = 0\n",
    "sample = df[df['标注类别名称'].str.split('-', expand=True)[part] == target_part]\n",
    "sample"
   ],
   "id": "98b47bb485e419fe",
   "outputs": [],
   "execution_count": null
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-27T11:19:31.361768Z",
     "start_time": "2025-09-27T11:19:07.883231Z"
    }
   },
   "cell_type": "code",
   "source": [
    "encoding_array = []\n",
    "img_path_list = []\n",
    "\n",
    "for img_path in tqdm(df['图片路径']):\n",
    "    img_path_list.append(img_path)\n",
    "    img_pil = Image.open(img_path)\n",
    "    input_img = transform(img_pil).unsqueeze(0).to(device) # 预处理\n",
    "    feature = model(input_img).squeeze().detach().cpu().numpy() # 执行前向预测，得到 avgpool 层输出的语义特征\n",
    "    encoding_array.append(feature)\n",
    "encoding_array = np.array(encoding_array)"
   ],
   "id": "6c22aee846fd45f8",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 5600/5600 [00:23<00:00, 238.69it/s]\n"
     ]
    }
   ],
   "execution_count": 6
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-27T11:19:46.263516Z",
     "start_time": "2025-09-27T11:19:46.256601Z"
    }
   },
   "cell_type": "code",
   "source": "encoding_array.shape",
   "id": "f96513e111f5b463",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(5600, 512)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 7
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-27T11:19:48.965169Z",
     "start_time": "2025-09-27T11:19:48.954638Z"
    }
   },
   "cell_type": "code",
   "source": "np.save(r'D:\\Code\\2-ZSL\\1-output\\特征解耦结果\\HOB\\exp-3\\特征投影.npy', encoding_array)",
   "id": "a464df6fef02e74c",
   "outputs": [],
   "execution_count": 8
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
